
#include <cstdlib>
#include <errno.h>
#include <sys/socket.h>

#include "network/AbstractClient.h"
#include "network/Server.h"

extern int errno;

uint32_t Server::suiMaxPendingConnections_ = 10;

Server::Server()
    : AbstractSocket()
{
}

Server::~Server()
{
    close();
}

bool Server::broadcast(void* data, uint32_t size)
{
    bool success = true;

    mutex_.lock();
    for(std::set<AbstractClient*>::iterator it = clients_.begin(); it != clients_.end(); ++it)
    {
        if((*it)->write(data, size) < 0)
        {
            success = false;
        }
    }
    mutex_.unlock();

    return success;
}

bool Server::close()
{
    // Fermeture de la socket d'écoute.
    bool ok = AbstractSocket::close();

    // Suppression des objets
    for(std::set<AbstractClient*>::iterator it = clients_.begin(); it != clients_.end(); ++it)
    {
        delete *it;
    }

    // Maj des références.
    clients_.clear();

    return ok;
}

bool Server::isListening() const
{
    return bIsListening_;
}

bool Server::listen(uint16_t port)
{
    // Création de la socket
    iSocket_ = socket(AF_INET, SOCK_STREAM, NULL);
    if(iSocket_ < 0)
    {
        iError_ = errno;
        return false;
    }

    // Paramétrage de la socket
    sin_.sin_addr.s_addr     = htonl(INADDR_ANY);
    sin_.sin_family          = AF_INET;
    sin_.sin_port            = htons(port);
    length_                  = sizeof(sin_);

    if(bind(iSocket_, (struct sockaddr*)&sin_, length_) < 0)
    {
        iError_ = errno;
        return false;
    }

    // Début de l'écoute
    if(::listen(iSocket_, suiMaxPendingConnections_) < 0)
    {
        iError_ = errno;
        return false;
    }

    bIsListening_ = true;
    return bIsListening_;
}

void Server::setMaxPendingConnections(int numConnections)
{
    suiMaxPendingConnections_ = numConnections;
}
